function MapOptions(div, state, onChange) {
  var that = this;
  this.state = state;
  this.onChange = onChange;
  this.div = $(div).submit(function(e) {
    return e.preventDefault();
  })
  .change(function() {
    that.updateState();
  });

  for (id in google.maps.MapTypeId) {
    if (google.maps.MapTypeId.hasOwnProperty(id) &&
        google.maps.MapTypeId[id].indexOf('__') == -1) {
      $('[name=mapTypeId]').append("<option value='" +
          google.maps.MapTypeId[id] + "'>" + id + "</option>");
    }
  }

  $('.setbounds-viewport', this.div).click(function() {
    wizard.boundsWidget.setBoundsToMap();
  });
  $('.setbounds-markers', this.div).click(function() {
    var bounds = new google.maps.LatLngBounds();
    var markerCollections = wizard.state.markerCollections;
    for (collection in markerCollections) {
      markerCollections[collection].extendBounds(bounds);
    }
    wizard.boundsWidget.setBounds(bounds);
  });
  $('.fitbounds', this.div).click(function() {
    if (state.map.useBounds) {
      wizard.map.fitBounds(state.map.bounds);
    }
  });
}

MapOptions.prototype.updateState = function() {
  var state = this.state;

  state.map.useBounds = $('[name=bounds]', this.div).attr('checked');

  //TODO(cbro): make this nicer
  $.each(['draggable', 'scrollwheel'], function(_, opt) {
      state.map[opt] = $('[name=' + opt + ']', this.div).attr('checked');
    });

  state.map.mapTypeId = $('[name=mapTypeId]', this.div).val();

  this.onChange && this.onChange(state);
};
